#include "termSelection.h"

/* Función auxiliar que calcula el logaritmo en
 * base 2 de unNumero, pasado por parámetro*/
double logBase2(double unNumero){
	double resultado = ( log(unNumero) / log(2) );
	return resultado;
}

/* Función auxiliar que calcula la probabilidad de
 * un evento que ocurre cantOcurrencia veces en un
 * espacio determinado por tamEspacio*/
double calcProbabilidad(double cantOcurrencia, unsigned int tamEspacio){
	double resultado = ( cantOcurrencia / tamEspacio );
	return resultado;
}

/* Función auxiliar que calcula la entropia de
 * un termino pasado por parametro en una lista
 * la cual indica las apariciones de dicho termino
 * en los distintos documentos*/
double calcEntropia(lista_t* aparicionesPalabra, unsigned int cantidadDocumentos, unsigned int totalOcurrencias){
	double P_ij, entropia = 0;
	elementoMatriz_t* unElemento = NULL;

	lista_iter_t* iter = lista_iter_crear(aparicionesPalabra);
	while ( ! lista_iter_al_final(iter))
	{
		unElemento = lista_iter_ver_actual(iter);
		P_ij = calcProbabilidad(unElemento->valor, totalOcurrencias);
		entropia += ( P_ij * log10(P_ij) );
		lista_iter_avanzar(iter);
	}

	lista_iter_destruir(iter);
	entropia = (entropia / log10(cantidadDocumentos));
	entropia += 1;
	return entropia;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de Información Mutua Puntual
 * (En inglés: Pointwise Mutual Information)*/
double metodoMI(unsigned int cantOcurrencias, unsigned int cantDocumentos){
	return 0;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de Ganancia de Información
 * (En inglés: Information Gain)*/
double metodoIG(unsigned int cantOcurrencias, unsigned int cantDocumentos){
	return 0;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de Coeficiente GSS*/
double metodoGSS(){
	return 0;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de Coeficiente NGL*/
double metodoNGL(){
	return 0;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de Calificación de Relevancia
 * (En inglés: Relevancy Score)*/
double metodoRS(){
	return 0;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de Relación de Probabilidades
 * (En inglés: Odds Ratio)*/
double metodoOR(){
	return 0;
}

/* Función que calcula la ponderación de un término
 * utilizando el método de TF*IDF, donde TF es la
 * frecuencia del término en un documento, e IDF es
 * la frecuencia inversa del documento*/
void metodoTFIDF(lista_t* aparicionesPalabra, unsigned int cantidadDocumentos){
	double tfidf = 0;
	unsigned int cantDocsConOcurrencia = lista_largo(aparicionesPalabra);
	elementoMatriz_t* unElemento = NULL;

	lista_iter_t* iter = lista_iter_crear(aparicionesPalabra);
	while ( ! lista_iter_al_final(iter))
	{
		unElemento = lista_iter_ver_actual(iter);
		tfidf = unElemento->valor * logBase2 ((double)cantidadDocumentos / (1 + cantDocsConOcurrencia));
		unElemento->valor = tfidf;
		lista_iter_avanzar(iter);
	}

	lista_iter_destruir(iter);
}

/* Función que calcula la ponderación de un término
 * mediante la multiplicación entre el logaritmo de
 * la frecuencia del término en un documento con
 * el valor de la entropa global de los documentos*/
void metodoLogEntropia(lista_t* aparicionesPalabra, unsigned int cantidadDocumentos, unsigned int totalOcurrencias){
	double log, entropia = 0;
	elementoMatriz_t* unElemento = NULL;

	entropia = calcEntropia(aparicionesPalabra, cantidadDocumentos, totalOcurrencias);

	lista_iter_t* iter = lista_iter_crear(aparicionesPalabra);
	while ( ! lista_iter_al_final(iter))
	{
		unElemento = lista_iter_ver_actual(iter);
		log = log10((unElemento->valor) + 1);
		unElemento->valor = (log * entropia);
		lista_iter_avanzar(iter);
	}

	lista_iter_destruir(iter);
}

